/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sbmart.smartserver.job;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sbmart.object.Header;
import sbmart.object.MstConnection;
import sbmart.smartserver.cache.DataSourcePool;
import sbmart.smartserver.task.ClientTrsSalesTask;

/**
 *
 * @author albert
 *
 */
public class ClientTrsSalesJob {

    private ExecutorService exec = null;
    private static Hashtable<Integer, List<Header>> headerPool = new Hashtable<Integer, List<Header>>();
    public static final Logger LOG = LoggerFactory.getLogger("ClientTrsSales");
    //public static final LoggerYM YM = LoggerYM.getLogger();
    public static int count = 0;
    private static int hours = 0;
    private static int date = 0;
    private static int date_old = 0;
    private static int HOUR_OFFSET = 14;
    private static int NUMBERS_OF_GROUP = 100;
    private static int noexec = 0;

    public void init() {

        HashMap<Integer, MstConnection> branchs = DataSourcePool.instance().getMstConnection();
        List<Header> headers = new ArrayList<Header>();

        for (Iterator<MstConnection> it = branchs.values().iterator(); it.hasNext();) {
            MstConnection branch = it.next();
            Header header = new Header();
            header.setBranchId(branch.getBranchId());
            header.setBranchName(branch.getBranchName());
            header.setNickname(branch.getNickname());
            header.setIpaddress(branch.getIpaddress());
            header.setUsername(branch.getUsername());
            header.setPassword(branch.getPassword());

            headers.add(header);
        }
        headerPool.put(Integer.valueOf(0), headers);
    }

    public void init2() {
        List<Header> headers = new ArrayList<Header>();
        List<Header> headers0 = new ArrayList<Header>();
        List<Header> headers1 = new ArrayList<Header>();
        List<Header> headers2 = new ArrayList<Header>();
        List<Header> headers3 = new ArrayList<Header>();
        List<Header> headers4 = new ArrayList<Header>();
        List<Header> headers5 = new ArrayList<Header>();
        List<Header> headers6 = new ArrayList<Header>();

        HashMap<Integer, MstConnection> branchs = DataSourcePool.instance().getMstConnection();

        for (Iterator<MstConnection> it = branchs.values().iterator(); it.hasNext();) {
            MstConnection branch = it.next();
            Header header = new Header();
            header.setBranchId(branch.getBranchId());
            header.setBranchName(branch.getBranchName());
            header.setNickname(branch.getNickname());
            header.setIpaddress(branch.getIpaddress());
            header.setUsername(branch.getUsername());
            header.setPassword(branch.getPassword());

            int g = header.getBranchId() / NUMBERS_OF_GROUP;

            switch (g) {
                case 0:
                    headers0.add(header);
                    break;
                case 1:
                    headers1.add(header);
                    break;
                case 2:
                    headers2.add(header);
                    break;
                case 3:
                    headers3.add(header);
                    break;
                case 4:
                    headers4.add(header);
                    break;
                case 5:
                    headers5.add(header);
                    break;
                case 6:
                    headers6.add(header);
                    break;
                default:
                    headers.add(header);
                    break;
            }

        }

        if (headers0.size() > 0) {
            headerPool.put(Integer.valueOf(0), headers0);
        }
        if (headers1.size() > 0) {
            headerPool.put(Integer.valueOf(1), headers1);
        }
        if (headers2.size() > 0) {
            headerPool.put(Integer.valueOf(2), headers2);
        }
        if (headers3.size() > 0) {
            headerPool.put(Integer.valueOf(3), headers3);
        }
        if (headers4.size() > 0) {
            headerPool.put(Integer.valueOf(4), headers4);
        }
        if (headers5.size() > 0) {
            headerPool.put(Integer.valueOf(5), headers5);
        }
        if (headers6.size() > 0) {
            headerPool.put(Integer.valueOf(6), headers6);
        }
        
        if (headers.size() > 0) {
            headerPool.put(Integer.valueOf(7), headers);
        }
        
        
    }

    public void runTasks() {
        LOG.debug("[RUN SMART SERVER]: " + count);
        try {

            hours = Calendar.getInstance().getTime().getHours();
            date = Calendar.getInstance().getTime().getDate();
            LOG.debug("[DATE]:" + date + " | [DATE_OLD]: " + date_old + " | [NOEXEC]:" + noexec);
            if (date > date_old) {
                noexec = 0;
                date_old = date;
            }

            if (exec == null || exec.isTerminated()) {
                count = 0;

                //YM.send("ClientTrsSales [RUN] TRUE : " + count);
                LOG.info("");
                LOG.info("");
                LOG.info("<TASK RUN> " + Calendar.getInstance().getTime().toString());
                if (exec != null) {
                    LOG.info("<TASK RUN> exec:" + exec.toString());
                } else {
                    LOG.info("<TASK RUN> exec is null");
                }
                executeTask();
            } else {
                count++;
                if (count > 1) {
                    //YM.sendBuzz();
                    //YM.send("ClientTrsSales [RUN] in progress : " + count);
                    LOG.info("ClientTrsSales [RUN] in progress : " + count);
                }

                if (count > 4) {
                    //YM.sendBuzz();
                    //YM.send("ServerTrs progress timeout, try to auto restart");
                    LOG.info("ServerTrs progress timeout, try to auto restart");
                    exec.shutdownNow();
                    Thread.currentThread().interrupt();
                    exec = null;
                }

            }
        } catch (Exception ex) {
            LOG.error("[ERROR] runTask", ex);
        } finally {
            LOG.debug("[RUN END]: " + count);
        }
    }

    private void executeTask() {
        headerPool.clear();
        if (hours < HOUR_OFFSET && noexec < 3) {
            init2();
//            init();
            LOG.debug("[INIT2]: HEADER_POOL size: " + headerPool.size());
            exec = Executors.newFixedThreadPool(headerPool.size());
            noexec++;
        } else {
            init();
            LOG.debug("[INIT1]: HEADER_POOL size: " + headerPool.size());
            exec = Executors.newSingleThreadExecutor();
        }

//        for (int i = 0; i < headerPool.size(); i++) {
//            exec.execute(new ClientTrsSalesTask(headerPool.get(i), exec));
//        }

        Iterator<List<Header>> headerIter = headerPool.values().iterator();
        while (headerIter.hasNext()) {
            List<Header> headers = headerIter.next();
            if (headers.size() > 0) {
                exec.execute(new ClientTrsSalesTask(headers, exec));
            }
        }

        exec.shutdown();
    }
}
